﻿using Smokey.Client.Contexts;
using Smokey.Client.Linq;
using Smokey.Client.Screens.Common;
using System;
using System.ComponentModel;
using System.Configuration;
using System.Diagnostics;
using System.Globalization;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Markup;
using System.Windows.Threading;
using Application = System.Windows.Application;

namespace Smokey.Client {
    public partial class App : Application {

        public App() {
            this.DispatcherUnhandledException += App_DispatcherUnhandledException;
            TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
            SetDefaultLanguage();
        }

        public static new App Current {
            get { return (App)Application.Current; }
        }

        internal MainWindow ApplicationWindow {
            get {
                if (this.MainWindow == null) {
                    this.MainWindow = new MainWindow();
                }

                return (MainWindow)this.MainWindow;
            }
        }
        internal ViewModelContext Context { get; private set; }

        protected override void OnStartup(StartupEventArgs e) {
            base.OnStartup(e);

            this.Context = new ViewModelContext(ApplicationWindow);
            this.ApplicationWindow.DataContext = this.Context;
            this.ApplicationWindow.Closing += MainWindow_Closing;

            this.ApplicationWindow.Show();

            if (TestDatabaseConnection(ConfigurationManager.AppSettings["ConnectionString"])) {
                this.Context.ShowApplicationSearchScreen();
            } else {
                this.Context.ShowConnectionStringSetupScreen();
            }
        }

        public bool TestDatabaseConnection(string connectionString) {
            if (string.IsNullOrWhiteSpace(connectionString)) {
                return false;
            }

            try {
                using (DBSession dbSession = DBSession.CreateDbSession(connectionString)) {
                    using (ModelDataContext context = ModelDataContext.CreateDataContext(dbSession)) {
                        return true;
                    }
                }
            } catch {
                return false;
            }
        }

        // Overrides en-US as the default language of all framework elements.
        private void SetDefaultLanguage() {
            string currentLanguage = CultureInfo.CurrentCulture.IetfLanguageTag;
            FrameworkElement.LanguageProperty.OverrideMetadata(
                typeof(FrameworkElement),
                new FrameworkPropertyMetadata(XmlLanguage.GetLanguage(currentLanguage)));
        }

        private void HandleException(Exception ex) {
            AggregateException aggregateException = ex as AggregateException;
            if (aggregateException != null) {
                aggregateException = aggregateException.Flatten();
                if (aggregateException.InnerExceptions.Count == 1) {
                    ex = aggregateException.InnerExceptions[0];
                }
            }

            if (ex.InnerException != null) {
                ex = ex.InnerException;
            }

            EventLog.WriteEntry("Smokey", ex.ToString(), EventLogEntryType.Error);

            ExceptionDialog exceptionDialog = new ExceptionDialog();
            exceptionDialog.Exception = ex;
            exceptionDialog.ShowDialog();
        }

        #region Events
        private void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) {
            HandleException(e.Exception);
        }

        private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e) {
            HandleException(e.Exception);
        }

        private void MainWindow_Closing(object sender, CancelEventArgs e) {
            MessageBoxResult rv = MessageBox.Show("Are you sure you want to exit?", "Smokey - Exit", MessageBoxButton.YesNo);
            if (rv != MessageBoxResult.Yes) {
                e.Cancel = true;
            }
        }
        #endregion
    }
}
